home *** CD-ROM | disk | FTP | other *** search
/ 8bitfiles.net/archives / archives.tar / archives / compuserve-file-archive / 07 CP_M / JTCP12.LBR / JETCP12.ZZ0 / JETCP12.Z80
Encoding:
Text File  |  1991-06-08  |  17.0 KB  |  948 lines

  1. ;
  2. ; Program:    JetCopy - High speed file copy for Z3PLUS
  3. ; Author:    Carson Wilson
  4. ; Assembly:    ZMAC, ZML, PARMLIB, ZSLIB, SYSLIB
  5. ; Version:    1.2
  6.  
  7. VERS    equ    12
  8.  
  9. ; Date:        31 Mar 90
  10. ; Changes:    Now skips stamp read if the file stamping is toggled off.
  11.  
  12. ; Version:    1.1
  13. ; Date:        23 Mar 90
  14. ; Changes:    Removed DMABUF for Set Stamp calls; use RAMPTR instead for even
  15. ;          more buffer space.  Also changed BUFnRECS storage to 1 byte 
  16. ;          each.
  17.  
  18. ; Version:    1.0
  19. ; Date:        22 Feb 90
  20. ; Changes:    Cleaned up output screens.
  21. ;        Added installable "no stamp" (/D) command line toggle.
  22. ;
  23. ; Version:    0.9
  24. ; Date:        16 Feb 90
  25. ; Changes:    Added test for validity of BCD stamp (CPM3 may return 00's).
  26. ;        Cleaned up exit code.
  27. ;        Checks for CP/M plus, and aborts if not found.
  28. ;        More explicit set stamp error messages.
  29. ;        Consolidated multiple read/write routines to save space.
  30. ;        Tells KBytes transferred instead of records.
  31. ;
  32. ; Version:    0.9
  33. ; Date:        7 Feb 90
  34. ; Changes:    Cleaned up code, bell on erase messages, better help, etc.
  35. ; Version:    0.8
  36. ;
  37. ; Date:        6 Feb 90
  38. ; Changes:    Use ZCPR error handler routines.
  39. ; Version:    0.7
  40. ;
  41. ; Initial version
  42. ; 12/14/89 C.Wilson
  43. ;
  44. ;    Usage:    CP [d:]source [d:]dest
  45. ;        CP d:source [d:][dest]
  46.  
  47.  
  48. FALSE    equ    0
  49. TRUE    equ    not false
  50.  
  51. PLUS    equ    TRUE            ; TRUE for Z3PLUS version
  52.  
  53. BELL    equ    07h
  54. BS    equ    08h
  55. TAB    equ    09h
  56. LF    equ    0Ah
  57. CR    equ    0Dh
  58.  
  59. BDOS    equ    5
  60. PRINTS    equ    9
  61. FOPEN    equ    15
  62. FCLOSE    equ    16
  63. FDEL    equ    19
  64. FREADS    equ    20
  65. FWRITS    equ    21
  66. FMAKE    equ    22
  67. CURDSK    equ    25
  68. SDMA    equ    26
  69. SFATT    equ    30
  70. FUSER    equ    32
  71. FREADR    equ    33
  72. FWRITR    equ    34
  73. FMULTI    equ    44
  74. ERMODE    equ    45
  75.  
  76. FCB1    equ    5Ch
  77. FCB2    equ    6Ch
  78. FCBLEN    equ    36
  79. FNAMELN    equ    12
  80. ROOFF    equ    9            ; Offset to R/O attribute
  81.  
  82. MULTILN    equ    128*128            ; One CP/M Plus Multi-Sector Full
  83.  
  84.  
  85.     EXTRN    CRLF, COUT, PRINT, PSTR, PFN2, PHLFDC, BIOS    ; SYSLIB
  86.     EXTRN    PAFDC
  87.  
  88.     EXTRN    GSTPCP, SSTPCP, ISBCDD, DOSTYP, DOSVER        ; ZSLIB
  89.  
  90.     EXTRN    PARGET                        ; PARMLIB
  91.  
  92.     PUBLIC    $MEMRY
  93.  
  94.     .request    PARLIB, ZSSSTPCP, ZSLIB, SYSLIB
  95.  
  96.  
  97. ; ================================================
  98.  
  99. ; PROGRAM BEGINS
  100.  
  101.     rst    0            ; Z34 only
  102.     dw    START
  103.     db    'Z3ENV'
  104.     db    1
  105. ENVADDR:
  106.     dw    0
  107.  
  108. ; Installable options
  109.  
  110.     db    '[OPTIONS>'
  111. DATEDEF:
  112.     db    0FFh            ; Default: DO stamp files
  113. START:
  114.     ld    (STKSAV),sp
  115.     ld    sp,STACK
  116.  
  117.     ld    hl,SIGNST
  118.     call    PSTR
  119.  
  120.     ld    hl,FCB1+1
  121.     ld    a,(hl)
  122.     cp    ' '
  123.     jp    z,HELP
  124.     cp    '?'
  125.     jp    z,HELP
  126.     cp    '/'
  127.     jr    nz,INIT
  128.     inc    hl
  129.     ld    a,(hl)
  130.     cp    '/'
  131.     jr    nz,INIT
  132.     inc    hl
  133.     ld    a,(hl)
  134.     cp    ' '
  135.     jp    z,HELP
  136. INIT:
  137.     call    DOSTYP
  138.     ld    a,(DOSVER)
  139.     cp    30h
  140.     jp    c,NOTC3
  141.  
  142. ; Check for [[/]options]
  143.  
  144.     ld    a,3
  145.     call    PARGET            ; Have 3rd parm?
  146.     jr    z,PARM2            ; No
  147.     cp    '/'
  148.     jr    z,PARM2A
  149.     jr    PARM2B
  150. PARM2:
  151.     ld    a,2            ; Have 2nd?
  152.     call    PARGET
  153.     jr    z,NOOPT            ; No.
  154.     cp    '/'            ; Yes, option?
  155.     jr    nz,NOOPT        ; No.
  156.     ld    a,' '
  157.     ld    (FCB2+1),a        ; Yes, flag 2nd FCB blank
  158. PARM2A:    inc    hl            ; Move to option character
  159. PARM2B:    ld    a,(hl)
  160.     cp    'D'            ; Stamp switch?
  161.     jp    nz,BADOPT        ; No, abort.
  162.     ld    a,(DATEDEF)        ; Yes, toggle default
  163.     cpl
  164.     jr    SAVOPT
  165. NOOPT:
  166.     ld    a,(DATEDEF)
  167. SAVOPT:    ld    (DATEOPT),a
  168.  
  169.     call    DIRCHEK
  170.     ld    a,(FCB1+13)
  171.     ld    (SUSER),a
  172.     ld    a,(FCB2+13)
  173.     ld    (DUSER),a
  174.     ld    hl,FCB2
  175.     ld    bc,FNAMELN
  176.     ld    de,CPFCB
  177.     ldir
  178.  
  179.     ld    h,d            ; Initialize rest
  180.     ld    l,e
  181.     inc    de
  182.     ld    (hl),0
  183.     ld    bc,FCBLEN-FNAMELN-1
  184.     push    bc    
  185.     ldir
  186.  
  187.     pop    bc            ; Initialize rest
  188.     ld    hl,FCB1+FNAMELN
  189.     ld    d,h
  190.     ld    e,l
  191.     inc    de
  192.     ld    (hl),0
  193.     ldir
  194.  
  195.     ld    c,CURDSK        ; Get current disk
  196.     call    BDOS
  197.     inc    a
  198.     ld    b,a
  199.     ld    a,(FCB1)
  200.     or    a
  201.     jr    nz,GOTDSK1
  202.     ld    a,b
  203.     ld    (FCB1),a
  204. GOTDSK1:
  205.     ld    a,(CPFCB)
  206.     or    a
  207.     jr    nz,GOTDSK2
  208.     ld    a,b
  209.     ld    (CPFCB),a
  210. GOTDSK2:
  211.     ld    a,(CPFCB+1)
  212.     cp    ' '            ; FCB2 was blank?
  213.     jr    nz,INIT1        ; No
  214.     ld    de,CPFCB+1        ; Yes, then copy from FCB1
  215.     ld    hl,FCB1+1
  216.     ld    bc,11
  217.     ldir
  218.  
  219.     ld    hl,FCB1+1        ; Check and abort on wildcards
  220.     call    IFWILD
  221.     ld    hl,CPFCB+1
  222.     call    IFWILD
  223.  
  224. ; Check duplicate filespecs
  225.  
  226.     ld    a,(SUSER)
  227.     ld    b,a
  228.     ld    a,(DUSER)
  229.     cp    b
  230.     jr    nz,INIT1        ; Not same if different users
  231.     ld    hl,FCB1
  232.     ld    de,CPFCB
  233.     ld    b,12
  234. DUPCHK:    ld    a,(de)
  235.     cp    (hl)
  236.     inc    de
  237.     inc    hl
  238.     jr    nz,INIT1        ; Not same if different filespecs
  239.     djnz    DUPCHK
  240.     jp    DUPERR            ; Abort if drive and name same
  241.  
  242. INIT1:                    ; Tell what we're copying
  243.     call    PRINT
  244.     db    ' Copying ',0
  245.     ld    a,(FCB1)
  246.     add    a,'@'
  247.     call    COUT
  248.     ld    a,(SUSER)
  249.     call    PAFDC
  250.     ld    a,':'
  251.     call    COUT
  252.     ld    de,FCB1+1
  253.     call    PFN2
  254.     call    PRINT
  255.     db    ' to ',0
  256.     ld    a,(CPFCB)
  257.     add    '@'
  258.     call    COUT
  259.     ld    a,(DUSER)
  260.     call    PAFDC
  261.     ld    a,':'
  262.     call    COUT
  263.     ld    de,CPFCB+1
  264.     call    PFN2
  265.     call    CRLF
  266.  
  267.     ld    a,(SUSER)        ; Open source file 
  268.     ld    e,a
  269.     ld    c,FUSER
  270.     call    BDOS
  271.     ld    de,FCB1
  272.     ld    c,FOPEN
  273.     call    BDOS
  274.     inc    a
  275.     jp    z,NOFLERR
  276.  
  277.     ld    a,(DATEOPT)        ; Do stamp?
  278.     or    a
  279.     jr    z,INIT2            ; No.
  280.  
  281.     ld    de,FCB1            ; Get source stamp
  282.     ld    hl,STPBUF
  283.     call    GSTPCP
  284.     ld    (GOTSTP),a
  285. INIT2:
  286.  
  287. ;
  288. ; Perform high-speed disk I/O
  289. ;
  290.  
  291. ; First initialize pointers
  292.  
  293.     xor    a
  294.     ld    (EOFFLG),a
  295.     ld    hl,0
  296.     ld    (XFERED),hl
  297.     ld    (BUF1PTR),hl
  298.     ld    (BUF1RECS),a
  299.     ld    (BUF2PTR),hl
  300.     ld    (BUF2RECS),a
  301.     ld    (BUF3PTR),hl
  302.     ld    (BUF3RECS),a
  303.     ld    (BUF4PTR),hl
  304.     ld    (BUF4RECS),a
  305.  
  306. ; Now allocate all free space for multisector read/write buffers (up to four)
  307.  
  308.     ld    bc,(RAMPTR)        ; Free RAM
  309.     call    FRECS
  310.     jp    c,TPAERR        ; TPA remaining < 128 bytes
  311.     ld    (BUF1PTR),bc
  312.     ld    (BUF1RECS),a
  313.     cp    128            ; Full buffer allocated?
  314.     jp    nz,INITX        ; No, init. done
  315.  
  316.     push    ix
  317.     pop    bc
  318.     call    FRECS
  319.     jp    c,INITX            ; TPA remaining < 128 bytes
  320.     ld    (BUF2PTR),bc
  321.     ld    (BUF2RECS),a
  322.     cp    128            ; Full buffer allocated?
  323.     jp    nz,INITX        ; No, init. done
  324.  
  325.     push    ix
  326.     pop    bc
  327.     call    FRECS
  328.     jp    c,INITX            ; TPA remaining < 128 bytes
  329.     ld    (BUF3PTR),bc
  330.     ld    (BUF3RECS),a
  331.     cp    128            ; Full buffer allocated?
  332.     jp    nz,INITX        ; No, init. done
  333.  
  334.     push    ix
  335.     pop    bc
  336.     call    FRECS
  337.     jp    c,INITX            ; TPA remaining < 128 bytes
  338.     ld    (BUF4PTR),bc
  339.     ld    (BUF4RECS),a        ; Has to be < 128 records
  340. INITX:
  341.  
  342. ; At this point we have allocated up to 4 buffers of 128 records or less.
  343. ; Each buffer's size is indicated by (BUFnRECS).
  344.  
  345.     call    PRINT
  346.     db    ' Reading ',0
  347.  
  348. ; Perform initial READ before making destination file for maximum throughput.
  349.  
  350.     call    READMLT
  351.     call    TELLK            ; Tell records read
  352.  
  353.     ld    a,(DUSER)
  354.     ld    e,a
  355.     ld    c,FUSER
  356.     call    BDOS
  357. MAKE:
  358.     call    TRAP            ; Return error mode
  359.     ld    de,CPFCB
  360.     ld    c,FMAKE
  361.     call    BDOS
  362.     call    UNTRAP            ; Default error mode
  363.  
  364.     or    a            ; Make OK?
  365.     jp    z,RWLP1            ; Yes
  366.     ld    a,h
  367.     cp    8            ; File exists?
  368.     jp    nz,FULERR        ; No, disk error
  369.     
  370.     call    PRINT
  371.     db    CR,LF,BELL,' Erase destination file (Y/N)? N',BS,0
  372.     call    CAPINE
  373.     call    CRLF
  374.     cp    'Y'
  375.     jp    nz,ABEXIT
  376. ERASE:
  377.     call    TRAP
  378.     ld    de,CPFCB
  379.     ld    c,FDEL
  380.     call    BDOS
  381.     call    UNTRAP
  382.     or    a            ; Delete OK?
  383.     jr    z,MAKE            ; Yes
  384.     ld    a,h
  385.     cp    3            ; No. File R/O?
  386.     jp    nz,FULERR        ; No, quit (disk R/O, etc.)
  387.     call    PRINT
  388.     db    BELL,' Erase R/O file (Y/N)? N',BS,0
  389.      call    CAPINE
  390.     call    CRLF
  391.     cp    'Y'
  392.     jp    nz,ABEXIT
  393.     ld    a,(CPFCB+ROOFF)
  394.     res    7,a
  395.     ld    (CPFCB+ROOFF),a
  396.     ld    de,CPFCB
  397.     ld    c,SFATT
  398.     call    BDOS
  399.     or    a
  400.     jp    nz,NOFLERR        ; Shouldn't happen, but just to be safe
  401.     jr    ERASE            ; Should work this time
  402.  
  403.  
  404. ; -----------------------------------
  405.  
  406. ;    MAIN COPY LOOP
  407.  
  408. ; -----------------------------------
  409.  
  410. RWLOOP:
  411.     call    PRINT
  412.     db    CR,TAB,TAB,TAB,TAB    ; Clear messages
  413.     db    CR,' Reading ',0
  414.     ld    a,(SUSER)
  415.     ld    e,a
  416.     ld    c,FUSER
  417.     call    BDOS
  418.     call    READMLT
  419.     call    TELLK
  420. RWLP1:                    ; Entry point from above
  421.     call    PRINT
  422.     db    ' Writing, ',0
  423.     ld    a,(DUSER)
  424.     ld    e,a
  425.     ld    c,FUSER
  426.     call    BDOS
  427.     call    WRITMLT
  428.     ld    a,(EOFFLG)
  429.     or    a
  430.     jr    z,RWLOOP
  431.     call    CLOSE            ; Close and stamp
  432.     jp    DONE
  433.  
  434. ; ========================================
  435. ;
  436. ;    SUBROUTINES
  437. ;
  438. ; ========================================
  439.  
  440. ; READMLT - Read Multi-Sector
  441.  
  442. READMLT:
  443.     xor    a            ; Reset counters
  444.     ld    (BUF1IN),a
  445.     ld    (BUF2IN),a
  446.     ld    (BUF3IN),a
  447.     ld    (BUF4IN),a
  448. ;
  449. ; Read until buffers filled or EOF
  450. ;
  451.     ld    de,(BUF1PTR)        ; Buffer address
  452.     ld    a,(BUF1RECS)        ; Buffer size; at least 1 record
  453.     call    BUFREAD            ; EOF?
  454.     ld    a,h            ; Records read if filled
  455.     ld    (BUF1IN),a
  456.     jr    z,EOF            ; EOF, quit
  457.     ld    a,(BUF1RECS)        ; Otherwise, buffer filled
  458.     ld    (BUF1IN),a
  459. READ2:    ld    a,(BUF2RECS)
  460.     or    a
  461.     ret    z            ; No space
  462.     ld    de,(BUF2PTR)
  463.     call    BUFREAD
  464.     ld    a,h            ; Records read if filled
  465.     ld    (BUF2IN),a
  466.     jr    z,EOF            ; EOF, quit
  467.     ld    a,(BUF2RECS)        ; Otherwise, buffer filled
  468.     ld    (BUF2IN),a
  469. READ3:    ld    a,(BUF3RECS)
  470.     or    a
  471.     ret    z            ; No space
  472.     ld    de,(BUF3PTR)
  473.     call    BUFREAD
  474.     ld    a,h            ; Records read if filled
  475.     ld    (BUF3IN),a
  476.     jr    z,EOF            ; EOF, quit
  477.     ld    a,(BUF3RECS)        ; Otherwise, buffer filled
  478.     ld    (BUF3IN),a
  479. READ4:    ld    a,(BUF4RECS)
  480.     or    a
  481.     ret    z            ; No space
  482.     ld    de,(BUF4PTR)
  483.     call    BUFREAD
  484.     ld    a,h            ; Records read if filled
  485.     ld    (BUF4IN),a
  486.     jr    z,EOF            ; EOF, quit
  487.     ld    a,(BUF4RECS)        ; Otherwise, buffer filled
  488.     ld    (BUF4IN),a
  489.     ret
  490. EOF:
  491.     ld    a,0FFh
  492.     ld    (EOFFLG),a
  493.     ret
  494. BUFREAD:
  495.     push    af            ; Save buffer size
  496.     ld    c,SDMA            ; Set to buffer
  497.     call    BDOS
  498.     pop    af
  499.     ld    e,a
  500.     ld    c,FMULTI        ; Set MULTI count
  501.     call    BDOS
  502.     ld    de,FCB1
  503.     ld    c,FREADS        ; Read (up to) 1st bufferful
  504.     call    BDOS
  505.     cp    2
  506.     jp    nc,UNKERR
  507.     cp    1            ; (Z) if EOF
  508.     ret
  509.  
  510.  
  511. ; -----------------------------------
  512.  
  513. ; WRTMLT - Write Multi-Sector
  514. ;     Write until buffers exhausted
  515. ;
  516. WRITMLT:
  517.     ld    a,(BUF1IN)        ; Test 1st buffer dirty
  518.     or    a
  519.     ret    z
  520.     ld    de,(BUF1PTR)        ; Buffer address
  521.     call    BUFWRIT
  522.     ld    a,(BUF2IN)        ; Test 1st buffer dirty
  523.     or    a
  524.     ret    z
  525.     ld    de,(BUF2PTR)        ; Buffer address
  526.     call    BUFWRIT
  527.     ld    a,(BUF3IN)        ; Test 1st buffer dirty
  528.     or    a
  529.     ret    z
  530.     ld    de,(BUF3PTR)        ; Buffer address
  531.     call    BUFWRIT
  532.     ld    a,(BUF4IN)        ; Test 1st buffer dirty
  533.     or    a
  534.     ret    z
  535.     ld    de,(BUF4PTR)        ; Buffer address
  536. ;    fall    thru
  537.  
  538. ; Write A records from buffer at DE to (CPFCB)
  539.  
  540. BUFWRIT:
  541.     push    af            ; Save records
  542.     ld    c,SDMA
  543.     call    BDOS
  544.     pop    af
  545.     ld    e,a            ; Set MULTI
  546.     ld    c,FMULTI
  547.     call    BDOS
  548.     ld    de,CPFCB
  549.     ld    c,FWRITS
  550.     call    BDOS
  551.     or    a
  552.     ret    z
  553.     jp    FWRITER            ; NZ means write error
  554.  
  555. ; ------------------------------------------------------
  556.  
  557. ; CLOSE - Close output file 
  558.  
  559. CLOSE:
  560.     ld    c,FCLOSE
  561.     ld    de,CPFCB
  562.     call    BDOS        ; BDOS aborts here on hard error
  563.     or    a
  564.     jp    nz,UNKERR    ; File not found (in case user switched disk)
  565.     ld    a,(DATEOPT)    ; Do stamp?
  566.     or    a
  567.     ret    z        ; No.
  568.     ld    a,(GOTSTP)    ; Stamp returned by CP/M3?
  569.     or    a
  570.     ret    nz        ; No.
  571.     ld    hl,STPBUF
  572.     call    ISBCDD        ; Check for validity (CPM3 may return 00's)
  573.     ret    nz
  574.     ld    de,CPFCB
  575.     ld    bc,(RAMPTR)    ; <crw>
  576.     call    SSTPCP
  577.     jp    nz,SSTPERR
  578.     call    PRINT
  579.     db    'Stamped, ',0
  580.     ret
  581.  
  582. ; ------------------------------------------
  583. ;
  584. ; TELLK - Tell how many kilobytes (or records) read so far
  585. ;
  586. TELLK:    ld    hl,(XFERED)
  587.     ld    b,0
  588.     ld    a,(BUF1IN)
  589.     ld    c,a
  590.     add    hl,bc
  591.     ld    a,(BUF2IN)
  592.     ld    c,a
  593.     add    hl,bc
  594.     ld    a,(BUF3IN)
  595.     ld    c,a
  596.     add    hl,bc
  597.     ld    a,(BUF4IN)
  598.     ld    c,a
  599.     add    hl,bc            ; HL holds total records Xfered
  600.     ld    (XFERED),hl
  601.  
  602.     xor    a
  603.     srl    h            ; Divide by 8 to get K
  604.     rr    l
  605.     rra                ; Save remainder
  606.     srl    h
  607.     rr    l
  608.     rra
  609.     srl    h
  610.     rr    l
  611.     rra
  612.     rra
  613.     rra
  614.     rra
  615.     rra
  616.     rra                ; A = remainder in records
  617.  
  618.     call    PHLFDC            ; Show K as up to 5 decimal
  619.     call    PRINT
  620.     db    'k ',0
  621.     call    PAFDC            ; Show records as 0..7
  622.     call    PRINT
  623.     db    'r,',0
  624.     ret
  625.  
  626. ; Reading 5k 0r, Writing, Stamped, Done.
  627.  
  628. ; -------------------------------------------
  629. ;
  630. ; FRECS - Get free TPA in records
  631. ;
  632. ;    Entry:    BC = buffer start
  633. ;    Exit:    (C)    - overflow error
  634. ;        (NC)    - A = free records
  635. ;            - IX = buffer end
  636. ;
  637. FRECS:    ld    hl,(BDOS+1)
  638.     ld    de,128
  639.     xor    a
  640.     sbc    hl,de            ; BDOS - 128 (never carries)
  641.     sbc    hl,bc            ; (BDOS-128-buffer) --> HL
  642.     ret    c            ; Overflow (BDOS-buffer < 128)
  643.     push    bc
  644.     pop    ix            ; IX = buffer start
  645.     add    hl,de            ; HL = free space in bytes
  646.     ld    a,1            ; Count free records (at least 1)
  647.     add    ix,de            ; ..keep buffer end
  648. FRECN:    sbc    hl,de
  649.     ret    z            ; Even
  650.     jr    c,FRECX            ; Past end
  651.     inc    a            ; Count last one
  652.     cp    129            ; Avoid overflow in A
  653.     jr    z,FRECX
  654.     add    ix,de            ; Count last one
  655.     jr    FRECN
  656. FRECX:
  657.     dec    a
  658.     and    a            ; Set to (NC)
  659.     ret    
  660. ;
  661. IFWILD:                    ; Check 11-byte filename for '?'
  662.     push    hl
  663.     push    bc
  664.     ld    b,11
  665. IFWIL1:    ld    a,(hl)
  666.     cp    '?'
  667.     jp    z,AMBIGERR
  668.     inc    hl
  669.     djnz    IFWIL1
  670.     pop    bc
  671.     pop    hl
  672.     ret
  673. ;
  674. BADOPT:
  675.     call    PRINT
  676.     db    BELL,'  Bad option: /',0
  677.     call    COUT
  678.     call    CRLF
  679.  
  680. HELP:    ld    hl,HELPST
  681.     jp    EXPRINT
  682.  
  683. DONE:    ld    hl,DONEST
  684.     jp    EXPRINT
  685.  
  686. ;
  687. TRAP:                    ; Trap CP/M+ errors 
  688.     ld    c,ERMODE
  689.     ld    e,0FFh            ; Return error mode
  690.     jp    BDOS
  691. ;
  692. UNTRAP:                    ; UnTrap CP/M+ errors 
  693.     push    af            ; Save result codes
  694.     push    hl
  695.     ld    c,ERMODE
  696.     ld    e,0            ; Default error mode
  697.     call    BDOS
  698.     pop    hl
  699.     pop    af
  700.     ret
  701. ;
  702. SPACE:
  703.     ld    a,' '
  704.     jp    COUT
  705.  
  706. CAPINE:                    ; Broken in SYSLIB 4.2
  707.     push    bc
  708.     push    de
  709.     push    hl
  710.     ld    a,3
  711.     call    BIOS
  712.     cp    'a'
  713.     jr    c,CAPIN1
  714.     and    01011111b        ; Lowercase it
  715. CAPIN1:    call    COUT
  716.     pop    hl
  717.     pop    de
  718.     pop    bc
  719.     ret
  720.  
  721. ; -----------------------------------
  722.  
  723. ;    ERROR ROUTINES
  724.  
  725. ; Routines to chain to Error Handler (EH)
  726.  
  727. ; 1.  Error codes (from ZCPR34.LBR)
  728.  
  729. ; ZCPR34 uses the error byte at the beginning of the message buffer as a flag
  730. ; to show what kind of error occurred.  Advanced error handlers will be able
  731. ; to help the user further by suggesting the possible cause of the error.
  732.  
  733. ecbaddir    equ    2    ; Bad directory specification -- logging of
  734.                 ; ..user number beyond legal range,
  735.                 ; ..nonexistent named directory
  736.  
  737. ecunknown    equ    4    ; EH unknown error
  738.  
  739. ecambig        equ    8    ; Ambiguous file specification where not
  740.                 ; ..allowed (SAVE, GET, REN)
  741. ecbadnum    equ    9    ; Bad numerical value -- not a number where
  742.                 ; ..number expected, number out of range
  743. ecnofile    equ    10    ; File not found -- REN, TYPE, LIST could not
  744.                 ; ..find a specified file
  745. ecdiskfull    equ    11    ; Disk directory or data area full
  746.                 ; ..(DOS write error)
  747. ectpafull    equ    12    ; TPA overflow error
  748. ecdupspec    equ    16    ; Duplicate filespecs
  749.  
  750. ; 2.  Error Routines
  751.  
  752. UnkErr:    ld    a,ecunknown
  753.     jr    errexit
  754.  
  755. TPAErr:    ld    a,ectpafull    ; TPA overflow
  756.     jr    errexit
  757.  
  758. AmbigErr:
  759.     ld    a,ecambig    ; Ambiguous filespec
  760.     jr    errexit
  761.  
  762. NoFlErr:            ; File missing
  763.     ld    a,ecnofile    ; File not found error
  764.     jr    errexit        ; Chain to error handler
  765.  
  766. FulErr:                ; Disk or directory full (BDOS write error)
  767.     ld    a,ecdiskfull    ; Disk or data area full
  768.     jr    errexit        ; Chain to error handler
  769. DupErr:                ; Duplicate file specs
  770.     ld    a,ecdupspec    ; Duplicate filespec error
  771.     jr    errexit        ; Chain to error handler
  772.  
  773. ; Check for illegal directory specification under ZCPR 3.4.
  774. ; DirChek assumes that FCB's have not been altered since they were
  775. ; set by the CCP.  Therefore DirChek is called before other BDOS calls. 
  776.  
  777. DirChek:
  778.     ld    a,(fcb1+15)    ; Z34 sets these to non zero
  779.     ld    hl,fcb2+15    ; ..if illegal dirspecs. found
  780.     or    (hl)
  781.     ret    z        ; Return if OK
  782.     ld    a,ecbaddir    ; Bad dir. error code
  783. ;    fall    thru
  784. ;
  785. ; Set error type, then set error, ECP, and external program bits of command 
  786. ;    status flag to tell CCP to go straight to EH.  
  787.  
  788. ErrExit:
  789.     ld    b,0
  790. ErrEx1:    ex    af,af'
  791.     ld    hl,(ENVADDR)
  792.     ld    de,34
  793.     add    hl,de
  794.     ld    a,(hl)
  795.     inc    hl
  796.     ld    h,(hl)
  797.     ld    l,a        ; HL points to message buffer
  798.     ex    af,af'
  799.     ld    (hl),a        ; First set error type in error byte
  800.     ld    a,00001110b    ; Tell CCP External, No ECP, Error, No shell
  801.     or    b        ; Add any specified bits
  802.     inc    hl
  803.     inc    hl
  804.     inc    hl
  805.     ld    (hl),a        ; Set bits in command status flag
  806.     jp    exit        ; Return to CCP
  807.  
  808. ; -------------------------------------------------------------
  809.  
  810. SSTPERR:            ; Report Set Stamp error
  811.     call    PRINT
  812.     db    CR,LF,' Set stamp error: ',0
  813.     ld    hl,SSER01
  814.     cp    1
  815.     jp    z,PSTR
  816.     ld    hl,SSER02
  817.     cp    2
  818.     jp    z,PSTR
  819.     ld    hl,SSER03
  820.     cp    3
  821.     jp    z,PSTR
  822.     ld    hl,SSER04
  823.     cp    4
  824.     jp    z,PSTR
  825.     ld    hl,SSER05
  826.     cp    5
  827.     jp    z,PSTR
  828.     ld    hl,SSERFF
  829.     cp    0FFh
  830.     jp    z,PSTR
  831.     ld    hl,SSERUN
  832.     jp    PSTR
  833.  
  834. SSER01:    db    'BIOS write ' 0
  835. SSER02:    db    'BIOS read ',0
  836. SSER03:    db    'drive invalid ',0
  837. SSER04:    db    'BIOS sectors > 1k ',0
  838. SSER05:    db    'no stamps on disk ',0
  839. SSERFF:    db    'file not found ',0
  840. SSERUN:    db    'unknown ',0
  841.  
  842. ;
  843. NOTC3:                ; Not CPM3
  844.     call    PRINT
  845.     db    CR,LF,' Requires Z3PLUS',0
  846.     jp    ABEXIT
  847.  
  848. FWRITER:            ; Write error
  849.     ld    de,CPFCB    ; Close file before quitting
  850.     ld    c,FCLOSE
  851.     call    BDOS        ; BDOS aborts here on hard error
  852.     or    a
  853.     jp    nz,UNKERR    ; File not found (in case user switched disk)
  854.     ld    de,CPFCB    ; File closed OK, now delete partial file
  855.     ld    c,FDEL
  856.     call    BDOS
  857.     jp    FULERR
  858.  
  859. EXPRINT:call    PSTR
  860.     jr    EXIT
  861.  
  862. ABEXIT:
  863.     call    PRINT
  864.     db    CR,LF,' JC aborting.',CR,LF,0
  865. EXIT:    ld    sp,(STKSAV)
  866.     ret
  867.  
  868. ; -------------------------------------
  869.  
  870. ;    DATA AREA
  871.  
  872. ;    INITALIZED DATA
  873.  
  874.  
  875. $MEMRY    equ    $
  876. RAMPTR:    dw    0000        ; Filled by linker 
  877.                 ; ..(allows linked modules w/DSEGS) <crw>
  878. SIGNST:
  879.     db    CR,LF,'JETCP'
  880.      if PLUS
  881.     db    '+'
  882.      endif
  883.     db    ', Vers. ',VERS / 10 + '0','.',VERS MOD 10 + '0'
  884.     db    ' - Copy Z3PLUS files, Copr. 1990 by C. Wilson',CR,LF
  885.     db    0
  886.  
  887. HELPST:
  888.     db    '  Usage:',CR,LF
  889.     db    TAB,'JC [dir:]ufn [dir:][ufn] [[/]options]',CR,LF
  890.     db    '  Options:',CR,LF
  891.     db    TAB,'D - toggle Datestamp',CR,LF
  892.     db    0
  893.  
  894. DONEST:
  895.     db    'Done.',CR,LF,0
  896.  
  897. ; -----------------------------------------------
  898. ;
  899. ;    UNINITIALIZED RAM
  900. ;
  901.  
  902.     DSEG
  903.  
  904. ; Copy FCB
  905.  
  906. CPFCB:    ds    FCBLEN
  907.  
  908. SUSER:    ds    1
  909. DUSER:    ds    1
  910.  
  911. ; Pointers & counters
  912.  
  913. BUF1PTR: ds    2
  914. BUF1RECS:ds    1
  915. BUF1IN:     ds    1
  916.  
  917. BUF2PTR: ds    2
  918. BUF2RECS:ds    1
  919. BUF2IN:     ds    1
  920.  
  921. BUF3PTR: ds    2
  922. BUF3RECS:ds    1
  923. BUF3IN:     ds    1
  924.  
  925. BUF4PTR: ds    2
  926. BUF4RECS:ds    1
  927. BUF4IN:     ds    1
  928.  
  929. XFERED:    ds    2
  930.  
  931. ; FLAGS
  932.  
  933. DATEOPT:ds    1    
  934. EOFFLG: ds    1    
  935. GOTSTP:    ds    1
  936.  
  937. ; BUFFERS
  938.  
  939. STKSAV:    ds    2
  940.     ds    50
  941. STACK:
  942.  
  943. STPBUF:    ds    128
  944.  
  945. ;DMABUF:    ds    1024        ; For CP/M+ set stamp
  946.  
  947.     end
  948.